namespace Avalonia.FuncUI.Diagnostics

open System
open System.Collections.Generic
open System.Collections.Concurrent

[<RequireQualifiedAccess>]
module HumanReadableGuid =

    let private animals: string list = List.ofArray [|
        "Canidae"
        "Felidae"
        "Cat"
        "Cattle"
        "Dog"
        "Donkey"
        "Goat"
        "Guinea pig"
        "Horse"
        "Pig"
        "Rabbit"
        "Fancy rat varieties"
        "laboratory rat strains"
        "Sheep breeds"
        "Water buffalo breeds"
        "Chicken breeds"
        "Duck breeds"
        "Goose breeds"
        "Pigeon breeds"
        "Turkey breeds"
        "Aardvark"
        "Aardwolf"
        "African buffalo"
        "African elephant"
        "African leopard"
        "Albatross"
        "Alligator"
        "Alpaca"
        "American buffalo (bison)"
        "American robin"
        "Amphibian"
        "list"
        "Anaconda"
        "Angelfish"
        "Anglerfish"
        "Ant"
        "Anteater"
        "Antelope"
        "Antlion"
        "Ape"
        "Aphid"
        "Arabian leopard"
        "Arctic Fox"
        "Arctic Wolf"
        "Armadillo"
        "Arrow crab"
        "Asp"
        "Ass (donkey)"
        "Baboon"
        "Badger"
        "Bald eagle"
        "Bandicoot"
        "Barnacle"
        "Barracuda"
        "Basilisk"
        "Bass"
        "Bat"
        "Beaked whale"
        "Bear"
        "list"
        "Beaver"
        "Bedbug"
        "Bee"
        "Beetle"
        "Bird"
        "list"
        "Bison"
        "Blackbird"
        "Black panther"
        "Black widow spider"
        "Blue bird"
        "Blue jay"
        "Blue whale"
        "Boa"
        "Boar"
        "Bobcat"
        "Bobolink"
        "Bonobo"
        "Booby"
        "Box jellyfish"
        "Bovid"
        "Buffalo, African"
        "Buffalo, American (bison)"
        "Bug"
        "Butterfly"
        "Buzzard"
        "Camel"
        "Canid"
        "Cape buffalo"
        "Capybara"
        "Cardinal"
        "Caribou"
        "Carp"
        "Cat"
        "list"
        "Catshark"
        "Caterpillar"
        "Catfish"
        "Cattle"
        "list"
        "Centipede"
        "Cephalopod"
        "Chameleon"
        "Cheetah"
        "Chickadee"
        "Chicken"
        "list"
        "Chimpanzee"
        "Chinchilla"
        "Chipmunk"
        "Clam"
        "Clownfish"
        "Cobra"
        "Cockroach"
        "Cod"
        "Condor"
        "Constrictor"
        "Coral"
        "Cougar"
        "Cow"
        "Coyote"
        "Crab"
        "Crane"
        "Crane fly"
        "Crawdad"
        "Crayfish"
        "Cricket"
        "Crocodile"
        "Crow"
        "Cuckoo"
        "Cicada"
        "Damselfly"
        "Deer"
        "Dingo"
        "Dinosaur"
        "list"
        "Dog"
        "list"
        "Dolphin"
        "Donkey"
        "list"
        "Dormouse"
        "Dove"
        "Dragonfly"
        "Dragon"
        "Duck"
        "list"
        "Dung beetle"
        "Eagle"
        "Earthworm"
        "Earwig"
        "Echidna"
        "Eel"
        "Egret"
        "Elephant"
        "Elephant seal"
        "Elk"
        "Emu"
        "English pointer"
        "Ermine"
        "Falcon"
        "Ferret"
        "Finch"
        "Firefly"
        "Fish"
        "Flamingo"
        "Flea"
        "Fly"
        "Flyingfish"
        "Fowl"
        "Fox"
        "Frog"
        "Fruit bat"
        "Gamefowl"
        "list"
        "Galliform"
        "list"
        "Gazelle"
        "Gecko"
        "Gerbil"
        "Giant panda"
        "Giant squid"
        "Gibbon"
        "Gila monster"
        "Giraffe"
        "Goat"
        "list"
        "Goldfish"
        "Goose"
        "list"
        "Gopher"
        "Gorilla"
        "Grasshopper"
        "Great blue heron"
        "Great white shark"
        "Grizzly bear"
        "Ground shark"
        "Ground sloth"
        "Grouse"
        "Guan"
        "list"
        "Guanaco"
        "Guineafowl"
        "list"
        "Guinea pig"
        "list"
        "Gull"
        "Guppy"
        "Haddock"
        "Halibut"
        "Hammerhead shark"
        "Hamster"
        "Hare"
        "Harrier"
        "Hawk"
        "Hedgehog"
        "Hermit crab"
        "Heron"
        "Herring"
        "Hippopotamus"
        "Hookworm"
        "Hornet"
        "Horse"
        "list"
        "Hoverfly"
        "Hummingbird"
        "Humpback whale"
        "Hyena"
        "Iguana"
        "Impala"
        "Irukandji jellyfish"
        "Jackal"
        "Jaguar"
        "Jay"
        "Jellyfish"
        "Junglefowl"
        "Kangaroo"
        "Kangaroo mouse"
        "Kangaroo rat"
        "Kingfisher"
        "Kite"
        "Kiwi"
        "Koala"
        "Koi"
        "Komodo dragon"
        "Krill"
        "Ladybug"
        "Lamprey"
        "Landfowl"
        "Land snail"
        "Lark"
        "Leech"
        "Lemming"
        "Lemur"
        "Leopard"
        "Leopon"
        "Limpet"
        "Lion"
        "Lizard"
        "Llama"
        "Lobster"
        "Locust"
        "Loon"
        "Louse"
        "Lungfish"
        "Lynx"
        "Macaw"
        "Mackerel"
        "Magpie"
        "Mammal"
        "Manatee"
        "Mandrill"
        "Manta ray"
        "Marlin"
        "Marmoset"
        "Marmot"
        "Marsupial"
        "Marten"
        "Mastodon"
        "Meadowlark"
        "Meerkat"
        "Mink"
        "Minnow"
        "Mite"
        "Mockingbird"
        "Mole"
        "Mollusk"
        "Mongoose"
        "Monitor lizard"
        "Monkey"
        "Moose"
        "Mosquito"
        "Moth"
        "Mountain goat"
        "Mouse"
        "Mule"
        "Muskox"
        "Narwhal"
        "Newt"
        "New World quail"
        "Nightingale"
        "Ocelot"
        "Octopus"
        "Old World quail"
        "Opossum"
        "Orangutan"
        "Orca"
        "Ostrich"
        "Otter"
        "Owl"
        "Ox"
        "Panda"
        "Panther"
        "Panthera hybrid"
        "Parakeet"
        "Parrot"
        "Parrotfish"
        "Partridge"
        "Peacock"
        "Peafowl"
        "Pelican"
        "Penguin"
        "Perch"
        "Peregrine falcon"
        "Pheasant"
        "Pig"
        "Pigeon"
        "list"
        "Pike"
        "Pilot whale"
        "Pinniped"
        "Piranha"
        "Planarian"
        "Platypus"
        "Polar bear"
        "Pony"
        "Porcupine"
        "Porpoise"
        "Portuguese man o' war"
        "Possum"
        "Prairie dog"
        "Prawn"
        "Praying mantis"
        "Primate"
        "Ptarmigan"
        "Puffin"
        "Puma"
        "Python"
        "Quail"
        "Quelea"
        "Quokka"
        "Rabbit"
        "list"
        "Raccoon"
        "Rainbow trout"
        "Rat"
        "Rattlesnake"
        "Raven"
        "Ray (Batoidea)"
        "Ray (Rajiformes)"
        "Red panda"
        "Reindeer"
        "Reptile"
        "Rhinoceros"
        "Right whale"
        "Roadrunner"
        "Rodent"
        "Rook"
        "Rooster"
        "Roundworm"
        "Saber-toothed cat"
        "Sailfish"
        "Salamander"
        "Salmon"
        "Sawfish"
        "Scale insect"
        "Scallop"
        "Scorpion"
        "Seahorse"
        "Sea lion"
        "Sea slug"
        "Sea snail"
        "Shark"
        "list"
        "Sheep"
        "list"
        "Shrew"
        "Shrimp"
        "Silkworm"
        "Silverfish"
        "Skink"
        "Skunk"
        "Sloth"
        "Slug"
        "Smelt"
        "Snail"
        "Snake"
        "list"
        "Snipe"
        "Snow leopard"
        "Sockeye salmon"
        "Sole"
        "Sparrow"
        "Sperm whale"
        "Spider"
        "Spider monkey"
        "Spoonbill"
        "Squid"
        "Squirrel"
        "Starfish"
        "Star-nosed mole"
        "Steelhead trout"
        "Stingray"
        "Stoat"
        "Stork"
        "Sturgeon"
        "Sugar glider"
        "Swallow"
        "Swan"
        "Swift"
        "Swordfish"
        "Swordtail"
        "Tahr"
        "Takin"
        "Tapir"
        "Tarantula"
        "Tarsier"
        "Tasmanian devil"
        "Termite"
        "Tern"
        "Thrush"
        "Tick"
        "Tiger"
        "Tiger shark"
        "Tiglon"
        "Toad"
        "Tortoise"
        "Toucan"
        "Trapdoor spider"
        "Tree frog"
        "Trout"
        "Tuna"
        "Turkey"
        "list"
        "Turtle"
        "Tyrannosaurus"
        "Urial"
        "Vampire bat"
        "Vampire squid"
        "Vicuna"
        "Viper"
        "Vole"
        "Vulture"
        "Wallaby"
        "Walrus"
        "Wasp"
        "Warbler"
        "Water Boa"
        "Water buffalo"
        "Weasel"
        "Whale"
        "Whippet"
        "Whitefish"
        "Whooping crane"
        "Wildcat"
        "Wildebeest"
        "Wildfowl"
        "Wolf"
        "Wolverine"
        "Wombat"
        "Woodpecker"
        "Worm"
        "Wren"
        "Xerinae"
        "X-ray fish"
        "Yak"
        "Yellow perch"
        "Zebra"
        "Zebra finch"
        "Animals by number of neurons"
        "Animals by size"
        "Common household pests"
        "Common names of poisonous animals"
        "Alpaca"
        "Bali cattle"
        "Cat"
        "Cattle"
        "Chicken"
        "Dog"
        "Domestic Bactrian camel"
        "Domestic canary"
        "Domestic dromedary camel"
        "Domestic duck"
        "Domestic goat"
        "Domestic goose"
        "Domestic guineafowl"
        "Domestic hedgehog"
        "Domestic pig"
        "Domestic pigeon"
        "Domestic rabbit"
        "Domestic silkmoth"
        "Domestic silver fox"
        "Domestic turkey"
        "Donkey"
        "Fancy mouse"
        "Fancy rat"
        "Lab rat"
        "Ferret"
        "Gayal"
        "Goldfish"
        "Guinea pig"
        "Guppy"
        "Horse"
        "Koi"
        "Llama"
        "Ringneck dove"
        "Sheep"
        "Siamese fighting fish"
        "Society finch"
        "Yak"
        "Water buffalo"
    |]

    let private colors: string list = List.ofArray [|
        "Black"
        "Blue"
        "Brown"
        "Green"
        "Grey"
        "Orange"
        "Pink"
        "Purple"
        "Red"
        "White"
        "Yellow"
        "Amber"
        "Aquamarine"
        "Azure"
        "Beige"
        "Bisque"
        "Coral"
        "Cornflower blue"
        "Crimson"
        "Cyan"
        "Dark blue"
        "Dark green"
        "Dark orange"
        "Dark red"
        "Gold"
        "Hot pink"
        "Indigo"
        "Lavender"
        "Lime green"
        "Magenta"
        "Maroon"
        "Mint green"
        "Navy blue"
        "Olive"
        "Orange red"
        "Orchid"
        "Pale green"
        "Pink"
        "Plum"
        "Salmon"
        "Silver"
        "Sky blue"
        "Spring green"
        "Tan"
        "Teal"
        "Turquoise"
        "Violet"
        "White"
    |]

    let private lookup: IDictionary<Guid, string> = ConcurrentDictionary<Guid, string>() :> _
    let private reverseLookup: IDictionary<string, Guid> = ConcurrentDictionary<string, Guid>() :> _

    let private sync = obj ()
    let private rng = Random 42
    let private getRandom () =
        let color = List.item (rng.Next(List.length colors)) colors
        let animal = List.item (rng.Next(List.length animals)) animals
        $"{color} {animal}"

    let internal fetch (identifier: Guid) : string =
        lock sync (fun _ ->
            match lookup.TryGetValue identifier with
            | true, value -> value
            | false, _ ->
                let mutable random = getRandom()

                while reverseLookup.ContainsKey random do
                    random <- getRandom()

                lookup.Add(identifier, random)
                reverseLookup.Add(random, identifier)

                random
        )

[<AutoOpen>]
module HumanReadableGuidExtensions =

    type Guid with
        member this.HumanReadable with get () =
            HumanReadableGuid.fetch this